package org.itstack.validator;


import org.itstack.model.aggregates.TreeRich;
import org.itstack.model.vo.TreeNode;
import org.itstack.model.vo.TreeNodeLink;
import org.itstack.model.vo.TreeRoot;

import java.util.List;
import java.util.Map;
import java.util.ArrayList;

/**
 * 决策树验证器
 * 验证决策树配置的正确性和完整性
 */
public class DecisionTreeValidator {
    
    /**
     * 验证决策树结构
     * @param treeRich 决策树
     * @return 验证结果
     */
    public ValidationResult validateTree(TreeRich treeRich) {
        ValidationResult result = new ValidationResult();
        
        try {
            // 基本结构验证
            if (!validateBasicStructure(treeRich)) {
                result.addError("决策树基本结构不完整");
                return result;
            }
            
            // 节点连接验证
            if (!validateNodeConnections(treeRich)) {
                result.addError("决策树节点连接存在问题");
                return result;
            }
            
            // 循环引用检测
            if (hasCircularReference(treeRich)) {
                result.addError("决策树存在循环引用");
                return result;
            }
            
            // 叶子节点验证
            if (!validateLeafNodes(treeRich)) {
                result.addError("决策树叶子节点配置不正确");
                return result;
            }
            
            result.setValid(true);
            result.addMessage("决策树验证通过");
            
        } catch (Exception e) {
            result.addError("验证过程中发生异常: " + e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 验证基本结构
     */
    private boolean validateBasicStructure(TreeRich treeRich) {
        if (treeRich == null) {
            return false;
        }
        
        TreeRoot treeRoot = treeRich.getTreeRoot();
        Map<Long, TreeNode> treeNodeMap = treeRich.getTreeNodeMap();
        
        if (treeRoot == null || treeNodeMap == null || treeNodeMap.isEmpty()) {
            return false;
        }
        
        if (treeRoot.getTreeRootNodeId() == null) {
            return false;
        }
        
        return treeNodeMap.containsKey(treeRoot.getTreeRootNodeId());
    }
    
    /**
     * 验证节点连接
     */
    private boolean validateNodeConnections(TreeRich treeRich) {
        TreeRoot treeRoot = treeRich.getTreeRoot();
        Map<Long, TreeNode> treeNodeMap = treeRich.getTreeNodeMap();
        
        for (TreeNode node : treeNodeMap.values()) {
            if (node.getNodeType() == 1) { // 决策节点
                List<TreeNodeLink> links = node.getTreeNodeLinkList();
                if (links == null || links.isEmpty()) {
                    return false;
                }
                
                // 验证链接的目标节点是否存在
                for (TreeNodeLink link : links) {
                    if (!treeNodeMap.containsKey(link.getNodeIdTo())) {
                        return false;
                    }
                }
            }
        }
        
        return true;
    }
    
    /**
     * 检测循环引用
     */
    private boolean hasCircularReference(TreeRich treeRich) {
        TreeRoot treeRoot = treeRich.getTreeRoot();
        Map<Long, TreeNode> treeNodeMap = treeRich.getTreeNodeMap();
        
        // 使用深度优先搜索检测循环
        boolean[] visited = new boolean[treeNodeMap.size() + 1];
        boolean[] recStack = new boolean[treeNodeMap.size() + 1];
        
        return hasCycle(treeRoot.getTreeRootNodeId(), treeNodeMap, visited, recStack);
    }
    
    private boolean hasCycle(Long nodeId, Map<Long, TreeNode> treeNodeMap, 
                           boolean[] visited, boolean[] recStack) {
        if (recStack[nodeId.intValue()]) {
            return true; // 发现循环
        }
        
        if (visited[nodeId.intValue()]) {
            return false; // 已访问过
        }
        
        visited[nodeId.intValue()] = true;
        recStack[nodeId.intValue()] = true;
        
        TreeNode node = treeNodeMap.get(nodeId);
        if (node != null && node.getNodeType() == 1) {
            for (TreeNodeLink link : node.getTreeNodeLinkList()) {
                if (hasCycle(link.getNodeIdTo(), treeNodeMap, visited, recStack)) {
                    return true;
                }
            }
        }
        
        recStack[nodeId.intValue()] = false;
        return false;
    }
    
    /**
     * 验证叶子节点
     */
    private boolean validateLeafNodes(TreeRich treeRich) {
        Map<Long, TreeNode> treeNodeMap = treeRich.getTreeNodeMap();
        
        for (TreeNode node : treeNodeMap.values()) {
            if (node.getNodeType() == 2) { // 叶子节点
                if (node.getNodeValue() == null || node.getNodeValue().trim().isEmpty()) {
                    return false;
                }
            }
        }
        
        return true;
    }
    
    /**
     * 验证结果类
     */
    public static class ValidationResult {
        private boolean valid = false;
        private List<String> errors = new ArrayList<>();
        private List<String> messages = new ArrayList<>();
        
        public boolean isValid() { return valid; }
        public void setValid(boolean valid) { this.valid = valid; }
        
        public List<String> getErrors() { return errors; }
        public List<String> getMessages() { return messages; }
        
        public void addError(String error) { errors.add(error); }
        public void addMessage(String message) { messages.add(message); }
        
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("验证结果: ").append(valid ? "通过" : "失败").append("\n");
            
            if (!messages.isEmpty()) {
                sb.append("消息:\n");
                for (String msg : messages) {
                    sb.append("  - ").append(msg).append("\n");
                }
            }
            
            if (!errors.isEmpty()) {
                sb.append("错误:\n");
                for (String error : errors) {
                    sb.append("  - ").append(error).append("\n");
                }
            }
            
            return sb.toString();
        }
    }
}
